namespace ScrumSprintMonitor.UI.Wpf
{
	#region #using Directives

	using System;
	using System.Windows;
	using System.Windows.Controls.Primitives;

	#endregion

	public class AnimatedUniformGrid : UniformGrid
	{
		public static readonly DependencyProperty DurationProperty = DependencyProperty.Register("Duration", typeof(Duration), typeof(AnimatedStackPanel),
		                                                                                         new UIPropertyMetadata(
		                                                                                         	new Duration(new TimeSpan(0, 0, 0, 0, 500))));

		private int _columns;
		private int _rows;

		// Using a DependencyProperty as the backing store for Duration.  This enables animation, styling, binding, etc...

		public Duration Duration
		{
			get { return (Duration) GetValue(DurationProperty); }
			set { SetValue(DurationProperty, value); }
		}

		/// <summary>
		/// Arranges the content of a <see cref="T:System.Windows.Controls.WrapPanel"/> element.
		/// </summary>
		/// <returns>
		/// The <see cref="T:System.Windows.Size"/> that represents the arranged size of this <see cref="T:System.Windows.Controls.WrapPanel"/> element and its children.
		/// </returns>
		/// <param name="arrangeSize">The <see cref="T:System.Windows.Size"/> that this element should use to arrange its child elements.
		///                 </param>
		protected override Size ArrangeOverride(Size arrangeSize)
		{
			var finalRect = new Rect(0.0, 0.0, arrangeSize.Width / this._columns, arrangeSize.Height / this._rows);
			var duration = Duration;
			double width = finalRect.Width;
			double num2 = arrangeSize.Width - 1.0;
			finalRect.X += finalRect.Width * FirstColumn;
			foreach (UIElement element in base.InternalChildren)
			{
				AnimatedPanelHelper.ArrangeChild(this, element, finalRect, duration);
				if (element.Visibility != Visibility.Collapsed)
				{
					finalRect.X += width;
					if (finalRect.X >= num2)
					{
						finalRect.Y += finalRect.Height;
						finalRect.X = 0.0;
					}
				}
			}
			return arrangeSize;
		}

		protected override Size MeasureOverride(Size constraint)
		{
			UpdateComputedValues();

			return base.MeasureOverride(constraint);
		}

		private void UpdateComputedValues()
		{
			this._columns = Columns;
			this._rows = Rows;
			if (FirstColumn >= this._columns)
			{
				FirstColumn = 0;
			}
			if ((this._rows == 0) || (this._columns == 0))
			{
				int visibleChildren = 0;
				int childIndex = 0;
				int count = base.InternalChildren.Count;
				while (childIndex < count)
				{
					var element = base.InternalChildren[childIndex];
					if (element.Visibility != Visibility.Collapsed)
					{
						visibleChildren++;
					}
					childIndex++;
				}
				if (visibleChildren == 0)
				{
					visibleChildren = 1;
				}
				if (this._rows == 0)
				{
					if (this._columns > 0)
					{
						this._rows = ((visibleChildren + FirstColumn) + (this._columns - 1)) / this._columns;
					}
					else
					{
						this._rows = (int) Math.Sqrt(visibleChildren);
						if ((this._rows * this._rows) < visibleChildren)
						{
							this._rows++;
						}
						this._columns = this._rows;
					}
				}
				else if (this._columns == 0)
				{
					this._columns = (visibleChildren + (this._rows - 1)) / this._rows;
				}
			}
		}
	}
}